package org.game.module.mailbo;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.google.common.collect.Maps;
import org.constant.MailConstant;
import org.error.GameErrorCode;
import org.game.constant.SessionConstent;
import org.game.db.bean.Mail;
import org.game.db.bean.Player;
import org.game.db.bean.ServerMail;
import org.game.db.cache.MailCache;
import org.game.db.cache.ServerMailCache;
import org.game.db.vo.BaseMail;
import org.game.log.builder.LogDsp;
import org.game.log.dsp.GoodsDsp;
import org.game.manager.ItemManager;
import org.game.manager.MailManager;
import org.game.module.EnterGameHandler;
import org.game.msgBuilder.MailMsgBuilder;
import org.game.protobuf.c2s.C2SMailMsg.MailHandleMsg;
import org.game.protobuf.c2s.C2SMailMsg.MailOperationType;
import org.game.protobuf.s2c.S2CMailMsg.MailInfoList;
import org.game.protobuf.s2c.S2CShareMsg.ChangeType;
import org.game.util.ProtoUnit;

import com.google.common.collect.Lists;
import com.sojoys.artifact.exception.AbstractLogicModelException;
import com.sojoys.artifact.factory.session.ISession;
import com.sojoys.artifact.tools.ToolError;
import com.sojoys.artifact.tools.ToolMap;
import com.xiaoleilu.hutool.util.StrUtil;
import org.utils.CommonUtil;

/**
 * 邮件 Created by fxf on 2017/7/26.
 */
public class MailBOImpl implements MailBO, EnterGameHandler {

	@Override
	public void enterGame(Player player) {
		
	}

	@Override
	public byte[] getMails(ISession session) throws AbstractLogicModelException {
		Player player = session.getAttr(SessionConstent.PLAYER);
		List<BaseMail> mails = Lists.newArrayList();
		
		// 个人邮件
		List<Mail> validMails = MailManager.me().checkTimeOutMail(player.getMailsFkPlayerId());
		mails.addAll(validMails);
		
		
		// 全服邮件
		List<ServerMail> serverMails = ServerMailCache.me().getCacheAll();
		for (ServerMail serverMail : serverMails) {
			if(MailManager.me().checkServerMailTimeOut(player, serverMail)){
				continue;
			}
			mails.add(serverMail);
		}
		
		// 检查邮件上限
		MailManager.me().checkMailMaxLimit(player,mails);
		
		
		
		MailInfoList mailInfoList = MailMsgBuilder.createMailInfoList(player,ChangeType.DEFAULT, mails);
		return ProtoUnit.toByte(mailInfoList);
	}

	
	@Override
	public byte[] operation(ISession session, MailHandleMsg mailMsg) throws AbstractLogicModelException {
		MailOperationType type = mailMsg.getType();
		List<Long> mailIds = new ArrayList<>(mailMsg.getIdsList().size());
		for (String idStr : mailMsg.getIdsList()) {
			mailIds.add(Long.valueOf(idStr));
		}
		
		Player player = session.getAttr(SessionConstent.PLAYER);
		switch (type) {
		case READ:
			return readMail(player,mailIds, mailMsg);
		case RECEIVE:
			return receiveMail(player,mailIds, mailMsg);
		case DELETE:
			return deleteMail(player,mailIds, mailMsg);
		}
		return null;
	}

	/**
	 * 读取邮件
	 * 
	 * @param player
	 * @param mailMsg
	 * @return
	 */
	private byte[] readMail(Player player,List<Long> mailIds, MailHandleMsg mailMsg) {
		
		List<BaseMail> updateMails = new ArrayList<>(mailIds.size());
		for (Long id : mailIds) {
			if (id > Integer.MAX_VALUE) {
				// 用户邮件				
				Mail mail = MailCache.me().getById(id);
				if(mail.getStatus() !=MailConstant.STATUS_DEFAULT ){
					continue;
				}
				mail.setStatus(MailConstant.STATUS_READ);
				mail.update();
				
				updateMails.add(mail);
			}else {
				// 服务器邮件
				ServerMail mail = ServerMailCache.me().getById(id.intValue());
				int state = (int) mail.getPidsStatus().computeIfAbsent(player.getId(), k->0);
				if(state != MailConstant.STATUS_DEFAULT){
					continue;
				}
				mail.getPidsStatus().put(player.getId(), MailConstant.STATUS_READ);
				mail.update();
				
				updateMails.add(mail);
			}
		}
		
		MailInfoList mailInfoList = MailMsgBuilder.createMailInfoList(player,ChangeType.UPDATE, updateMails,MailConstant.STATUS_READ);
		player.getPlayerProxy().sendMsg(MailBO.getMails,mailInfoList);
		return new byte[0];
	}

	/**
	 * 收取邮件
	 * 
	 * @param player
	 * @param mailMsg
	 * @return
	 */
	private byte[] receiveMail(Player player,List<Long> mailIds, MailHandleMsg mailMsg) {
		
		List<BaseMail> updateMails = new ArrayList<>(mailIds.size());
		Map<Integer,Integer> items = Maps.newHashMap();
		for (Long id : mailIds) {
			int status = MailConstant.STATUS_DEFAULT;
			if (id > Integer.MAX_VALUE) {
				// 用户邮件				
				Mail mail = MailCache.me().getById(id);
				ToolError.isAndTrue(GameErrorCode.CLIENT_PARAM_IS_ERR,"数据并非本账号数据",mail.getPlayerId()!=player.getId());
				status = mail.getStatus();
				if(status == MailConstant.STATUS_RECEIVE){
					continue;
				}
				CommonUtil.changeMap(items,mail.getItems());
				updateMails.add(mail);
			}else {
				// 服务器邮件
				ServerMail mail = ServerMailCache.me().getById(id.intValue());
				status = ToolMap.getInt(player.getId(), mail.getPidsStatus(),MailConstant.STATUS_DEFAULT);
				if(status == MailConstant.STATUS_RECEIVE){
					continue;
				}
				CommonUtil.changeMap(items,mail.getItems());
				updateMails.add(mail);
			}
			
			
			ToolError.isAndTrue(GameErrorCode.BAG_SPACE_IS_NOT_ENOUGH, !ItemManager.checkBackpackSpace(player, items));
			
			// 已领 || 已删
			ToolError.isAndTrue(GameErrorCode.MAIL_STATUS_ERROR, status == MailConstant.STATUS_RECEIVE || status == MailConstant.STATUS_DELETE);
		}
		
		for (BaseMail baseMail : updateMails) {
			if (baseMail instanceof Mail) {
				Mail mail =  (Mail) baseMail;
				mail.setStatus(MailConstant.STATUS_RECEIVE);
				mail.update();
			}else if(baseMail instanceof ServerMail){
				ServerMail mail = (ServerMail) baseMail;
				mail.getPidsStatus().put(player.getId(), MailConstant.STATUS_RECEIVE);
				mail.update();								
			}
			
			// 领取附件
			Map<Integer, Integer> goods = baseMail.getItems();
			LogDsp log ;
			if (StrUtil.isBlank(baseMail.getDsp())) {
				log = LogDsp.newBuilder(GoodsDsp.RECEIVE_MAIL);
			}else {
				log = LogDsp.newBuilder(baseMail.getDsp());					
			}
			
			ItemManager.addGoodsAndPush(player, null, null, goods, log);
		}
		
		MailInfoList mailInfoList = MailMsgBuilder.createMailInfoList(player,ChangeType.UPDATE, updateMails,MailConstant.STATUS_RECEIVE);
		player.getPlayerProxy().sendMsg(MailBO.getMails,mailInfoList);
		return new byte[0];
	}

	/**
	 * 删除邮件
	 * 
	 * @param player
	 * @param mailMsg
	 * @return
	 */
	private byte[] deleteMail(Player player,List<Long> mailIds, MailHandleMsg mailMsg) {
		List<BaseMail> updateMails = new ArrayList<>(mailIds.size());
		for (Long id : mailIds) {
			int status = MailConstant.STATUS_DEFAULT;
			Map items = null;
			if (id > Integer.MAX_VALUE) {
				// 用户邮件				
				Mail mail = MailCache.me().getById(id);
				status = mail.getStatus();
				items = mail.getItems();
				updateMails.add(mail);
			}else {
				// 服务器邮件
				ServerMail mail = ServerMailCache.me().getById(id.intValue());
				status = ToolMap.getInt(player.getId(), mail.getPidsStatus(),MailConstant.STATUS_DEFAULT);
				items = mail.getItems();
				updateMails.add(mail);
			}
			// 邮件还未领取
			ToolError.isAndTrue(GameErrorCode.NOT_RECEIVE_ITEMS, !items.isEmpty() && status != MailConstant.STATUS_RECEIVE);
			
			// 已删除 || 未读
			ToolError.isAndTrue(GameErrorCode.MAIL_STATUS_ERROR, status == MailConstant.STATUS_DELETE || status == MailConstant.STATUS_DEFAULT);
			
		}
		
		for (BaseMail baseMail : updateMails) {
			if (baseMail instanceof Mail) {
				Mail mail =  (Mail) baseMail;
				mail.delete();
//				mail.setStatus(MailConstant.STATUS_DELETE);
//				mail.update();
			}else if(baseMail instanceof ServerMail){
				ServerMail mail = (ServerMail) baseMail;
				mail.getPidsStatus().put(player.getId(), MailConstant.STATUS_DELETE);
				mail.update();								
			}
		}
		
		MailInfoList mailInfoList = MailMsgBuilder.createMailInfoList(player,ChangeType.DELETE, updateMails,MailConstant.STATUS_READ);
		player.getPlayerProxy().sendMsg(MailBO.getMails,mailInfoList);
		return new byte[0];
	}
}
